#if defined _dukehacks_included
 #endinput
#endif
#define _dukehacks_included

#include <core>


/**
 * @brief enums
 */
 
enum ClientHookType
{
	CHK_TraceAttack = 0,  // deprecated, use CHK_TakeDamage
	CHK_ProcessUsercmds,
	CHK_PreThink,
	CHK_PostThink,
	CHK_TakeDamage,
	CHK_Regenerate,
	CHK_Other
};

enum EntityHookType
{
	EHK_Touch = 0,
	EHK_VPhysicsUpdate,
	EHK_Transmit,
	EHK_Other
};

funcenum Hooks
{
	/**** clients ****/
	
	// TraceAttack hook (pre) (client)
	Action:public(client, attacker, inflictor, Float:Damage, &Float:damageMultiplier),
	// ProcessUsercmds hook (pre) (client)
	Action:public(client, &buttons, &impulse),
	// PreThink hook (pre) (client)
	// PostThink hook (pre) (client)
	// Regenerate hook (client)
	Action:public(client),
	// TakeDamage hook (pre) (client)
	Action:public(client, attacker, inflictor, Float:Damage, &Float:damageMultiplier, damagetype),
	
	/**** entities ****/
	
	// Touch hook (pre)
	// Transmit hook (pre)
	Action:public(entity, other),
	// VPhysicsUpdate hook
	Action:public(entity)
};
 
/**
 * @brief Called whenever an entity is created (currently only entities with an edict index)
 *        Using GetEdictClasName and similar functions can cause the server to crash.
 *        For most applications, you should use dhOnEntitySpawned instead. 
 *
 * @param edict		Index of the edict.
 * @return			Pl_Continue
 */
forward ResultType:dhOnEntityCreated(edict);

/**
 * @brief Called whenever an entity is spawned (currently only entities with an edict index)
 *
 * @param edict		Index of the edict.
 * @return			Pl_Continue
 */
forward ResultType:dhOnEntitySpawned(edict);

/**
 * @brief Called whenever an entity is deleted (currently only entities with an edict index)
 *
 * @param edict		Index of the edict.
 * @return			Pl_Continue
 */
forward ResultType:dhOnEntityDeleted(edict);

/**
 * @brief Add hook to all clients (players) [for example: TraceAttack]
 *
 * @param type			type of hook.
 * @param func			function name to send the hook to.
 * @return				none
 */
native dhAddClientHook(ClientHookType:type, Hooks:func);

/**
 * @brief	Add hook to specified entity (for example: Touch hook)
 *			(entities will automatically be unhooked by the extension
 *			when they are deleted)
 *
 * @param entity		entity to hook
 * @param type			type of hook.
 * @param func			function name to send the hook to.
 * @return				none
 */
native dhHookEntity(entity, EntityHookType:type, Hooks:func);


/**
 * @brief	Removes a hook from a specified entity (for example: Touch hook)
 *			(entities will automatically be unhooked by the extension
 *			when they are deleted)
 *
 * @param entity		entity to unhook
 * @param type			type of hook.
 * @return				none
 */
native dhUnHookEntity(entity, EntityHookType:type);


/**
 * @brief	applies damage to a player or entity
 *
 * @param entity		entity to damage
 * @param attacker		player/entity attacking
 * @param inflictor		player/entity doing damage (generally same as attacker unless attacker uses an object/projectile)
 * @param damage		damage to apply
 * @param damagetype	type of damage (DMG_BULLET, DMG_FALL, etc.)
 * @return				false if entity/attacker/inflictor are invalid
 *						true otherwise
 */
native dhTakeDamage(entity, attacker, inflictor, Float:damage, damagetype);

	
/**
 * @brief Game defines
 */
 
/* buttons */
#define IN_ATTACK		(1 << 0)
#define IN_JUMP			(1 << 1)
#define IN_DUCK			(1 << 2)
#define IN_FORWARD		(1 << 3)
#define IN_BACK			(1 << 4)
#define IN_USE			(1 << 5)
#define IN_CANCEL		(1 << 6)
#define IN_LEFT			(1 << 7)
#define IN_RIGHT		(1 << 8)
#define IN_MOVELEFT		(1 << 9)
#define IN_MOVERIGHT	(1 << 10)
#define IN_ATTACK2		(1 << 11)
#define IN_RUN			(1 << 12)
#define IN_RELOAD		(1 << 13)
#define IN_ALT1			(1 << 14)
#define IN_ALT2			(1 << 15)
#define IN_SCORE		(1 << 16)   // Used by client.dll for when scoreboard is held down
#define IN_SPEED		(1 << 17)	// Player is holding the speed key
#define IN_WALK			(1 << 18)	// Player holding walk key
#define IN_ZOOM			(1 << 19)	// Zoom key for HUD zoom
#define IN_WEAPON1		(1 << 20)	// weapon defines these bits
#define IN_WEAPON2		(1 << 21)	// weapon defines these bits
#define IN_BULLRUSH		(1 << 22)
#define IN_GRENADE1		(1 << 23)	// grenade 1
#define IN_GRENADE2		(1 << 24)	// grenade 2

/*  damage  */
// NOTE: TF2 seems to redefine some of the middle flags
//       for example, a crit attack passes DMG_ACID.
//       Adding DMG_ACID will not make an attack critical though. :(
#define DMG_GENERIC			0			// generic damage was done
#define DMG_CRUSH			(1 << 0)	// crushed by falling or moving object. 
										// NOTE: It's assumed crush damage is occurring as a result of physics collision, so no extra physics force is generated by crush damage.
										// DON'T use DMG_CRUSH when damaging entities unless it's the result of a physics collision. You probably want DMG_CLUB instead.
#define DMG_BULLET			(1 << 1)	// shot
#define DMG_SLASH			(1 << 2)	// cut, clawed, stabbed
#define DMG_BURN			(1 << 3)	// heat burned
#define DMG_VEHICLE			(1 << 4)	// hit by a vehicle
#define DMG_FALL			(1 << 5)	// fell too far
#define DMG_BLAST			(1 << 6)	// explosive blast damage
#define DMG_CLUB			(1 << 7)	// crowbar, punch, headbutt
#define DMG_SHOCK			(1 << 8)	// electric shock
#define DMG_SONIC			(1 << 9)	// sound pulse shockwave
#define DMG_ENERGYBEAM		(1 << 10)	// laser or other high energy beam 
#define DMG_PREVENT_PHYSICS_FORCE		(1 << 11)	// Prevent a physics force 
#define DMG_NEVERGIB		(1 << 12)	// with this bit OR'd in, no damage type will be able to gib victims upon death
#define DMG_ALWAYSGIB		(1 << 13)	// with this bit OR'd in, any damage type can be made to gib victims upon death.
#define DMG_DROWN			(1 << 14)	// Drowning
#define DMG_PARALYZE		(1 << 15)	// slows affected creature down
#define DMG_NERVEGAS		(1 << 16)	// nerve toxins, very bad
#define DMG_POISON			(1 << 17)	// blood poisoning - heals over time like drowning damage
#define DMG_RADIATION		(1 << 18)	// radiation exposure
#define DMG_DROWNRECOVER	(1 << 19)	// drowning recovery
#define DMG_ACID			(1 << 20)	// toxic chemicals or acid burns
#define DMG_SLOWBURN		(1 << 21)	// in an oven
#define DMG_REMOVENORAGDOLL	(1<<22)		// with this bit OR'd in, no ragdoll will be created, and the target will be quietly removed.
										// use this to kill an entity that you've already got a server-side ragdoll for
#define DMG_PHYSGUN			(1<<23)		// Hit by manipulator. Usually doesn't do any damage.
#define DMG_PLASMA			(1<<24)		// Shot by Cremator
#define DMG_AIRBOAT			(1<<25)		// Hit by the airboat's gun
#define DMG_DISSOLVE		(1<<26)		// Dissolving!
#define DMG_BLAST_SURFACE	(1<<27)		// A blast on the surface of water that cannot harm things underwater
#define DMG_DIRECT			(1<<28)
#define DMG_BUCKSHOT		(1<<29)		// not quite a bullet. Little, rounder, different.

/**
 * Do not edit below this line!
 */
public Extension:__ext_dukehacks =
{
	name = "Dukehacks Extension",
	file = "dukehacks.ext",
#if defined AUTOLOAD_EXTENSIONS
	autoload = 1,
#else
	autoload = 0,
#endif
#if defined REQUIRE_EXTENSIONS
	required = 1,
#else
	required = 0,
#endif
};

#if !defined REQUIRE_EXTENSIONS
public __ext_dukehacks_SetNTVOptional()
{
	MarkNativeAsOptional("dhAddClientHook");
	MarkNativeAsOptional("dhHookEntity");
	MarkNativeAsOptional("dhUnHookEntity");
	MarkNativeAsOptional("dhTakeDamage");
}
#endif
